/**
 * Copyright (C) 2016 Webank Group Holding Limited
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.jic.weamop.weBankAMOP.server;

import lombok.extern.slf4j.Slf4j;
import org.bcos.web3j.utils.Async;
import org.bcos.web3j.utils.AttemptsConf;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;

/**
 * 公共配置类，所有模块共用。
 *
 * @author jonyang
 */
@Configuration
@ComponentScan
@EnableScheduling
@EnableAsync
@EnableCaching
@Slf4j
public class NodeFrontConfiguration extends WebMvcConfigurerAdapter {


    @Value("${sdk.pool.corePoolSize}")
    private int corePoolSize;

    @Value("${sdk.pool.maxPoolSize}")
    private int maxPoolSize;

    @Value("${sdk.pool.queueCapacity}")
    private int queueCapacity;

    @Value("${sdk.pool.keepAliveSeconds}")
    private int keepAliveSeconds;

    @Value("${sdk.sleepDuration}")
    private int sleepDuration;

    @Value("${sdk.attempts}")
    private int attempts;

    @Bean(name = "messageSource")
    public MessageSource messageResource() {
        ReloadableResourceBundleMessageSource messageResource =
                new ReloadableResourceBundleMessageSource();
        messageResource.setBasename("classpath:messages");
        messageResource.setDefaultEncoding("UTF-8");
        messageResource.setCacheSeconds(3600);
        return messageResource;
    }


    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor(
            @Value("${threadpool.core-pool-size:48}") int backendCorePoolSize,
            @Value("${threadpool.keep-alive-seconds:60}") int backendKeepAliveSeconds,
            @Value("${threadpool.max-pool-size:48}") int backendMaxPoolSize,
            @Value("${threadpool.queue-capacity:300}") int backendQueueCapacity,
            @Value("${threadpool.allow-core-thread-timeout:true}") boolean backendAllowCoreThreadTimeOut,
            @Value("${threadpool.await-termination-seconds:60}") int backendAwaitTerminationSeconds,
            @Value("${threadpool.wait-for-task-to-complete-on-shutdown:true}") boolean waitForTasksToCompleteOnShutdown) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(backendCorePoolSize);
        executor.setKeepAliveSeconds(backendKeepAliveSeconds);
        executor.setMaxPoolSize(backendMaxPoolSize);
        executor.setQueueCapacity(backendQueueCapacity);
        executor.setAllowCoreThreadTimeOut(backendAllowCoreThreadTimeOut);
        executor.setAwaitTerminationSeconds(backendAwaitTerminationSeconds);
        executor.setWaitForTasksToCompleteOnShutdown(waitForTasksToCompleteOnShutdown);
        executor.setRejectedExecutionHandler(new AbortPolicy());
        return executor;
    }


    @Bean(name = "async")
    public Async  async(){
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(corePoolSize);
        pool.setMaxPoolSize(maxPoolSize);
        pool.setKeepAliveSeconds(keepAliveSeconds);
        pool.setQueueCapacity(queueCapacity);
        AbortPolicy  abortPolicy = new AbortPolicy();
        pool.setRejectedExecutionHandler(abortPolicy);
        pool.initialize();
        Async  async = new Async(pool);
        return async;
    }

    @Bean(name = "attemptsConf")
    public AttemptsConf attemptsConf(){
        AttemptsConf attemptsConf = new AttemptsConf(sleepDuration,attempts);
        return attemptsConf;
    }



}

